#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <sys/ioctl.h>

#define UART_DEVICE "/dev/ttyS3"

void set485Control(int fd, int enable)
{
    ioctl(fd, TIOCMGET, &fd);
    if (enable)
    {
        fd |= TIOCM_RTS;
    }
    else
    {
        fd &= ~TIOCM_RTS;
    }
    ioctl(fd, TIOCMSET, &fd);
}

void set485Send(int fd)
{
    system("./485_1.sh 1");
    set485Control(fd, 1);
}

void set485Receive(int fd)
{
    system("./485_1.sh 0");
    set485Control(fd, 0);
}

int main(int argc, char *argv[])
{
    int fd, ret, fd2;
    struct termios old_cfg = {0}; //用于保存终端配置之前的参数
    struct termios new_cfg = {0}; //用于保存终端新配置的参数
    speed_t speed = B115200;      //定义波特率为115200
    // speed_t speed = B2000000;
    /*第一步，串口初始化*/
    fd = open(UART_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY); //O_NOCTTY 标志，告知系统该节点不会成为进程的控制终端
    if (fd < 0)
    {
        printf("uart device open error\n");
        return -1;
    }

    /*打开485控制设备*/
    fd2 = open("/dev/ttyS3", O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd2 < 0)
    {
        printf("Open max485_ctl failed\n");
        return -1;
    }

    ret = tcgetattr(fd, &old_cfg);
    if (ret < 0)
    {
        printf("tcgetattr error\n");
        close(fd);
        return -1;
    }

    /*第二步，配置串口参数*/
    cfmakeraw(&new_cfg);        //设置为原始模式
    new_cfg.c_cflag |= CREAD;   // 使能接收
    cfsetspeed(&new_cfg, speed);//将波特率设置为115200
    new_cfg.c_cflag &= ~CSIZE;  //将数据位相关的比特位清零
    new_cfg.c_cflag |= CS8;     //将数据位数设置为8位
    new_cfg.c_cflag &= ~PARENB;
    new_cfg.c_iflag &= ~INPCK;  //设置为无校验模式
    new_cfg.c_cflag &= ~CSTOPB; //将停止位设置为1位
    new_cfg.c_cc[VTIME] = 0;    // 将 MIN 和 TIME 设置为 0
    new_cfg.c_cc[VMIN] = 0;
    ret = tcflush(fd, TCIOFLUSH); //清空缓冲区域
    if (ret < 0)
    {
        printf("tcflush error\n");
        return -1;
    }
    ret = tcsetattr(fd, TCSANOW, &new_cfg); //写入配置、使配置生效
    if (ret < 0)
    {
        printf("tcsetattr error\n");
        return -1;
    }

    set485Receive(fd); // 设置为接收模式

    char buff[100];
    while (1)
    {
        ret = read(fd, buff, sizeof(buff) - 1);
        buff[ret] = 0;
        if (ret < 0)
        {
            printf("read failed\n");
        }
        else if (ret > 0)
        {
            printf("Received message: %s\n", buff);

            // 回复相同的消息
            set485Send(fd); // 设置为发送模式
            write(fd, buff, strlen(buff));
            printf("485-1 测试成功\n");
            system("echo \"$(date)：485-1 测试成功\" >> /userfs/all.txt");
            set485Receive(fd); // 设置为接收模式
        }
        sleep(1);
    }

    tcsetattr(fd, TCSANOW, &old_cfg); //恢复到之前的配置
    close(fd);
    return 0;
}



//  #include <stdio.h>
// #include <sys/types.h>
// #include <sys/stat.h>
// #include <fcntl.h>
// #include <unistd.h>
// #include <string.h>
// #include <termios.h>
// #include <sys/ioctl.h>

// #define UART_DEVICE "/dev/ttyS3"

// void set485Control(int fd, int enable)
// {
//     int control;
//     ioctl(fd, TIOCMGET, &control);
//     if (enable)
//     {
//         control |= TIOCM_RTS;
//     }
//     else
//     {
//         control &= ~TIOCM_RTS;
//     }
//     ioctl(fd, TIOCMSET, &control);
// }

// void set485Send(int fd)
// {
//     system("./485_1.sh 1");
//     set485Control(fd, 1);
// }

// void set485Receive(int fd)
// {
//     system("./485_1.sh 0");
//     set485Control(fd, 0);
// }

// void write_to_485(int fd, const char *message)
// {
//     set485Send(fd);
//     write(fd, message, strlen(message));
//     set485Receive(fd);
// }

// int main(int argc, char *argv[])
// {
//     int fd, ret;
//     struct termios old_cfg = {0};
//     struct termios new_cfg = {0};
//     speed_t speed = B115200;

//     fd = open(UART_DEVICE, O_RDWR | O_NOCTTY | O_NDELAY);
//     if (fd < 0)
//     {
//         printf("uart device open error\n");
//         return -1;
//     }

//     ret = tcgetattr(fd, &old_cfg);
//     if (ret < 0)
//     {
//         printf("tcgetattr error\n");
//         close(fd);
//         return -1;
//     }

//     cfmakeraw(&new_cfg);
//     new_cfg.c_cflag |= CREAD;
//     cfsetspeed(&new_cfg, speed);
//     new_cfg.c_cflag &= ~CSIZE;
//     new_cfg.c_cflag |= CS8;
//     new_cfg.c_cflag &= ~PARENB;
//     new_cfg.c_iflag &= ~INPCK;
//     new_cfg.c_cflag &= ~CSTOPB;
//     new_cfg.c_cc[VTIME] = 0;
//     new_cfg.c_cc[VMIN] = 0;
//     ret = tcflush(fd, TCIOFLUSH);
//     if (ret < 0)
//     {
//         printf("tcflush error\n");
//         return -1;
//     }
//     ret = tcsetattr(fd, TCSANOW, &new_cfg);
//     if (ret < 0)
//     {
//         printf("tcsetattr error\n");
//         return -1;
//     }

//     set485Receive(fd);

//     char send_buffer[100]; // 用于保存发送的消息
//     char recv_buffer[100]; // 用于保存接收的消息
//     int send_count = 0; // 用于计数发送次数

//     while (send_count < 3) // 发送次数达到3次后退出循环
//     {
//         // 准备发送的消息
//         snprintf(send_buffer, sizeof(send_buffer), "Test message to 485 %d", send_count + 1);
        
//         // 模拟向485发送数据
//         write_to_485(fd, send_buffer);
//         send_count++; // 增加计数
//         printf("Sent message count: %d\n", send_count);
        
//         usleep(10000); // 延时一段时间等待接收完成
        
//         // 读取自发自收的数据
//         ret = read(fd, recv_buffer, sizeof(recv_buffer) - 1);
//         recv_buffer[ret] = 0; // 字符串结束标志
        
//         printf("Received message: %s\n", recv_buffer);

//         // 检查发送的消息和接收的消息是否相同
//         if (strcmp(send_buffer, recv_buffer) == 0) // 比较发送和接收的内容
//         {
//             printf("485-1测试成功\n");
//             // 记录成功测试的时间
//             system("echo \"$(date) 485-1 测试成功\" >> /userfs/all.txt");
//         }

//         sleep(1); // 等待一段时间再进行下一次发送
//     }

//     printf("Sent 3 messages, exiting...\n");

//     tcsetattr(fd, TCSANOW, &old_cfg);
//     close(fd);
//     return 0;
// }
